package com.atguigu.lease.common.utils;

import com.atguigu.lease.common.exception.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;

public class JwtUtil {
    //okenExpiration 表示令牌过期时间为60分
    private static long tokenExpiration = 60 * 60 * 1000L;
    //secretKey 使用指定密钥字符串生成一个HMAC-SHA算法所需的密钥对象，用于后续的JWT签名或验证操作
//    使用 Keys.hmacShaKeyFor 方法从一个字符串的字节数组生成 HMAC-SHA 密钥
//    密钥长度取决于输入字符串的字节长度，此处字符串长度为 32 字节，对应 HMAC-SHA-256
    private static SecretKey secretKey = Keys.hmacShaKeyFor("M0PKKI6pYGVWWfDZw90a0lTpGYX1d4AQ".getBytes());
    public static String createToken(Long userId, String username) {
        String token = Jwts.builder().
                setSubject("USER_INFO").
                setExpiration(new Date(System.currentTimeMillis() + tokenExpiration)).
                claim("userId", userId).
                claim("username", username).
                signWith(secretKey).
                compressWith(CompressionCodecs.GZIP).
                compact();
        return token;
    }//Claims 是一个核心概念，它表示 JWT 中包含的声明（即 JSON 对象）。这些声明是关于用户或其他实体的陈述，可分为三种类型：注册声明、公开声明和私有声明。
     //这些声明是关于用户或其他实体的陈述，可分为三种类型：注册声明、公开声明和私有声明。
    public static Claims parseToken(String token) {
        try {
            //创建一个解析器
            Jws<Claims> claimsJws = Jwts.parserBuilder().
                    //设置签名秘钥用于验证Token
                    setSigningKey(secretKey).
                    //调用方法解析验证Token
                    build().parseClaimsJws(token);
            //返回解析后的Claim对象(包含Token中所有的声明）
            return claimsJws.getBody();
        } catch (ExpiredJwtException e) {
            throw new LeaseException(ResultCodeEnum.TOKEN_EXPIRED.getMessage(), ResultCodeEnum.PARAM_ERROR.getCode());
        } catch (JwtException e) {
            throw new LeaseException(ResultCodeEnum.TOKEN_INVALID.getMessage(), ResultCodeEnum.TOKEN_INVALID.getCode());
        }
    }
}
